//
// Copyright (C) [2024] Xingyun Integrated Circuit Co., Ltd.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#include "ArchInfoGPGPU.h"

#include "AddressFilteringRegulator.h"
#include "AddressFilteringRegulatorGPGPU.h"
#include "AddressSolutionFilter.h"
#include "AddressTableManagerGPGPU.h"
#include "BootOrderGPGPU.h"
#include "ExceptionRecords.h"
#include "GenCondition.h"
#include "GenExceptionAgentGPGPU.h"
#include "GenInstructionAgent.h"
#include "GenQueryAgent.h"
#include "GenSequenceAgentGPGPU.h"
#include "GeneratorGPGPU.h"
#include "Log.h"
#include "MemoryTraitsGPGPU.h"
#include "PageRequestRegulatorGPGPU.h"
#include "PhysicalPageManagerGPGPU.h"
#include "Register.h"
#include "RegisterGPGPU.h"
#include "VmManagerGPGPU.h"

using namespace std;

namespace Green {

  ArchInfoGPGPU::ArchInfoGPGPU(const std::string& name)
    : ArchInfoBase(name)
  {
  }

  void ArchInfoGPGPU::Setup()
  {
    mMemoryBanks.push_back(EMemBankType::Default);
  }

  Generator* ArchInfoGPGPU::InstantiateGenerator() const
  {
    return new GeneratorGPGPU();
  }

  std::list<EVmRegimeType> ArchInfoGPGPU::VmRegimeTypes() const
  {
    list<EVmRegimeType> regime_types;
    regime_types.push_back(EVmRegimeType::M);
    regime_types.push_back(EVmRegimeType::S);
    regime_types.push_back(EVmRegimeType::HS);
    regime_types.push_back(EVmRegimeType::VS);

    return regime_types;
  }

  VmManager* ArchInfoGPGPU::InstantiateVmManager() const
  {
    return new VmManagerGPGPU();
  }

  GenAgent* ArchInfoGPGPU::InstantiateGenAgent(EGenAgentType agentType) const
  {
    switch (agentType) {
    case EGenAgentType::GenExceptionAgent:
      return new GenExceptionAgentGPGPU();
    case EGenAgentType::GenSequenceAgent:
      return new GenSequenceAgentGPGPU();
      /*
    case EGenAgentType::GenQueryAgent:
      return new GenQueryAgentGPGPU();
    case EGenAgentType::GenInstructionAgent:
      return new GenInstructionAgentGPGPU();
      */
    default:
      return ArchInfoBase::InstantiateGenAgent(agentType);
    }

    return nullptr;
  }

  BootOrder* ArchInfoGPGPU::InstantiateBootOrder() const
  {
    return new BootOrderGPGPU();
  }

  RegisterFile* ArchInfoGPGPU::InstantiateRegisterFile() const
  {
    return new RegisterFileGPGPU();
  }

  ExceptionRecordManager* ArchInfoGPGPU::InstantiateExceptionRecordManager() const
  {
    return new ExceptionRecordManager();
    // return new ExceptionRecordManagerGPGPU();
  }

  GenConditionSet* ArchInfoGPGPU::InstantiateGenConditionSet() const
  {
    return new GenConditionSet();
    // return new GenConditionSetGPGPU();
  }

  PhysicalPageManager* ArchInfoGPGPU::InstantiatePhysicalPageManager(EMemBankType bankType, MemoryTraitsManager* pMemTraitsManager) const
  {
    return new PhysicalPageManagerGPGPU(bankType, pMemTraitsManager);
  }

  MemoryTraitsRegistry* ArchInfoGPGPU::InstantiateMemoryTraitsRegistry() const
  {
    return new MemoryTraitsRegistryGPGPU();
  }

  PageRequestRegulator* ArchInfoGPGPU::InstantiatePageRequestRegulator() const
  {
    return new PageRequestRegulatorGPGPU();
  }

  AddressFilteringRegulator* ArchInfoGPGPU::InstantiateAddressFilteringRegulator() const
  {
    return new AddressFilteringRegulatorGPGPU();
  }

  AddressTableManager* ArchInfoGPGPU::InstantiateAddressTableManager() const
  {
    return new AddressTableManagerGPGPU();
  }

  AddressSolutionFilter* ArchInfoGPGPU::InstantiateAddressSolutionFilter(EAddressSolutionFilterType filterType) const
  {
    switch (filterType) {
    case EAddressSolutionFilterType::BaseDependency:
      return new BaseDependencyFilter();
    case EAddressSolutionFilterType::IndexDependency:
      return new IndexDependencyFilter();
    case EAddressSolutionFilterType::SpAlignment:
      return new SpAlignmentFilter();
    default:
      LOG(fail) << "{ArchInfoGPGPU::InstantiateAddressSolutionFilter} unsupported AddressSolutionFilter type: " << EAddressSolutionFilterType_to_string(filterType) << endl;
      FAIL("unsupported-address-solution-filter-type");
    }

    return nullptr;
  }
}
